home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows News 2010 Summer - Disc 1
/
WN_Ete2010_CD1.iso
/
Onglet5
/
Weezo
/
Weezo setup.exe
/
{code_appDir}
/
www
/
includes
/
transferFunctions.php
< prev
next >
Wrap
PHP Script
|
2010-05-19
|
43KB
|
978 lines
<?php
/**
* Transfers (uploads, remote downloads) visualisation scripts
* Includes :
* - transfer class
* - transfer misc functions
* - a page display script divided into 2 parts :
* - display in a frame (with head and body stuff), self-refreshed with async requests, for inclusion by explorer pages
* - display in div, for inclusion by administration / transfers page
*
* Images : view, slideshow, next, prev, fullSize
* HTML : view webpage (and not source code)
* text : inline view
* other formats : download (Opera) or inline view if possible (IE)
*
* parameters : POST data1 (file directory), data2 (file name), data3 (="view"), data4 (action (optional)), data5 (parameters (optional))
*
* PHP version 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category NA
* @package NA
* @author Nicolas Bruley / Peer 2 World <contact@weezo.net>
* @copyright 2005-2009 Nicolas Bruley / Peer 2 World
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id:$
* @link http://www.weezo.net
* @since File available since Release 1.0.0
*/
/*
***************************************************************************************************************************
* Transfer Class
***************************************************************************************************************************
*/
class transfer{
// Common variables
public $id; // (unique) Id of transfer
public $sessionId; // Session ID of user requesting transfer
public $sessionIP; // IP adress of user who initiated the transfer
public $type; // 'remoteDownload', 'upload', 'download', or 'bittorrentDownload'
public $status; // Transfer status
public $size; // Transfer total size
/*
* status values :
* created = 0
* waitConfirm = 1
* waitConnection = 2
* running = 3
* finished = 4
* paused = 5
* canceled = 6
* connecting = 7
* failed = 8
* removed = 9
*/
public $updateInterval; // Transfer update-to-file interval, in seconds (used for download monitoring)
// Common
public $progress; // transfer progress (0-1)
public $destinationFile; // Destination file (all transfers)
// Remote download and upload specific
public $destinationDir; // Destination directory (remoteDownload & updload)
// Remote download & download & bittorrent download specific
public $sourceFile;
// Remote download specific
public $URL;
public $host;
public $path;
// bittorrent download specific
public $userId; // (unique) id of user used to create torrent file. Used for speed limitation purposes
public $infoHash; // Url encoded 20 bytes SHA1 hash of bencoded torrent's info dictionnary
public $trackerIdSet; // True if "tracker id" sent to client
public $filesOffsets; // list of files and offsets. Format : file_path:eof_offset|file_path:eof_offset|...
public $pieces; // Number of pieces in torrent
public $pieceLength; // Piece size, in bytes
public $sentDataLength; // Nb of bytes sent
public $linkedTransferToken;// id of linked directLink or publishDownload token
// Constructor
function __construct($transferType){
if($transferType=='remoteDownload') $this->id="RDL";
elseif($transferType=='upload') $this->id="UL";
elseif($transferType=='download') $this->id="DL";
elseif($transferType=='multipleDownload') $this->id="MDL";
elseif($transferType=='bittorrentDownload') $this->id="BTDL";
else return false;
$this->id.=rand(0,999999999);
$this->type=$transferType;
$this->sessionId=wSession_id();
$this->sessionIP=$_SERVER['REMOTE_ADDR'];
$this->status=0;
$this->progress=0;
if($transferType=='upload') $this->updateInterval=0.1; else $this->updateInterval=3;
$this->startTime=time();
$this->destinationDir=false;
$this->destinationFile=false;
$this->sourceFile=false;
$this->URL=false;
$this->host=false;
$this->path=false;
$this->userId=false;
$this->infoHash=false;
$this->pieces=false;
$this->pieceLength=false;
$this->trackerIdSet=false;
$this->sentDataLength=0;
$this->linkedTransferToken=false;
$this->lastUpdated=time();
return $this->id;
}
// Destructor
function __destruct(){}
// Transfer "detail" string
public function detail($useBR=false){
$output='';
if($this->type=='upload') {
$output .= cfCaption('genFileUpload')."<br>\n";
$output .= cfCaption('genStartedTime').cfCaption('genSeparator').date(cfCaption('_FULL_DATE_FORMAT'),$this->startTime)."<br>\n";
$output .= cfCaption('transferCfgSource').cfCaption('genSeparator').$this->sessionIP.'://?/'.cfUTF8Encode($this->sourceFile)."<br>\n";
$output .= cfCaption('transferCfgDest').cfCaption('genSeparator').cfUTF8Encode($this->destinationDir.'/'.$this->destinationFile."<br>\n");
$output .= cfCaption('genState').cfCaption('genSeparator').$this->captionStatus().' ('.floor(100*$this->progress).'%)'."<br>\n";
}
elseif($this->type=='download') {
$output .= cfCaption('transfersDownload')."<br>\n";
$output .= cfCaption('genStartedTime').cfCaption('genSeparator').date(cfCaption('_FULL_DATE_FORMAT'),$this->startTime)."<br>\n";
$output .= cfCaption('transferCfgSource').cfCaption('genSeparator').cfUTF8Encode($this->sourceFile."<br>\n");
$output .= cfCaption('transferCfgDest').cfCaption('genSeparator').$this->sessionIP.'://?/'.cfUTF8Encode(basename($this->sourceFile))."<br>\n";
$output .= cfCaption('genState').cfCaption('genSeparator').($this->captionStatus()).' ('.floor(100*$this->progress).'%)'."<br>\n";
}
elseif($this->type=='remoteDownload') {
$output .= cfCaption('genDirectDownload')."<br>\n";
$output .= cfCaption('genStartedTime').cfCaption('genSeparator').date(cfCaption('_FULL_DATE_FORMAT'),$this->startTime)."<br>\n";
$output .= cfCaption('transferCfgSource').cfCaption('genSeparator').cfUTF8Encode($this->URL)."<br>\n";
$output .= cfCaption('transferCfgDest').cfCaption('genSeparator').cfUTF8Encode($this->destinationFile)."<br>\n";
$output .= cfCaption('genState').cfCaption('genSeparator').$this->captionStatus().' ('.floor(100*$this->progress).'%)'."<br>\n";
}
elseif($this->type=='multipleDownload') {
$output .= cfCaption('explorerMultipleDownload')."<br>\n";
$output .= cfCaption('genStartedTime').cfCaption('genSeparator').date(cfCaption('_FULL_DATE_FORMAT'),$this->startTime)."<br>\n";
$output .= cfCaption('transferCfgSource').cfCaption('genSeparator').cfUTF8Encode($this->sourceFile)."<br>\n";
$output .= cfCaption('transferCfgDest').cfCaption('genSeparator').cfUTF8Encode($this->destinationFile)."<br>\n";
$output .= cfCaption('genState').cfCaption('genSeparator').$this->captionStatus().' ('.floor(100*$this->progress).'%)'."<br>\n";
}
elseif($this->type=='bittorrentDownload') {
$output .= 'Bittorrent'."<br>\n";
$output .= cfCaption('genStartedTime').cfCaption('genSeparator').date(cfCaption('_FULL_DATE_FORMAT'),$this->startTime)."<br>\n";
$output .= cfCaption('genState').cfCaption('genSeparator').$this->captionStatus().' ('.floor(100*$this->progress).'%)'."<br>\n";
$output .= cfCaption('transferCfgSource').cfCaption('genSeparator')."<br>\n";
foreach (explode('|',$this->sourceFile) as $file) if($file!='') $output.=' - '.cfUTF8Encode($file)."<br>\n";
require_once(INCLUDE_DIR.'explorerFunctions.php');
$output .= cfCaption('genSize').cfCaption('genSeparator').efFileSizeFormat($this->size);
}
if($useBR) return ($output); else return str_replace("\n",'',$output);
}
/**
* save upload in uploads.txt file or to memory
* @param array $transfersArray: whole array of transfers. If omitted, reload from memory or file
* @param boolean $commitToFile: true to force commit to file, false to save to memory only
*/
public function commitToFile($transfersArray=false,$commitToFile=true){
if(!$transfersArray) $transfersArray=tReadTransfersFiles();
$transfersArray[$this->id]=$this;
$result=tWritePHPTransfersFile($transfersArray,$commitToFile);
unset($transfersArray);
return $result;
}
/**
* @desc Check if transfer is still in transfers array or if it has been removed
*
* @return boolean true if still in transfers array
*/
public function exists(){
$transfers=tReadTransfersFiles(false);
return isset($transfers[$this->id]);
}
/**
* @desc Return status label (non-utf8 encoded)
*
* @return string status
*/
public function captionStatus(){
switch ($this->status){
case 1: return cfCaption('transfersWaitConfirm');
case 2: return cfCaption('transfersWaitConnection');
case 3: return cfCaption('transfersWorking');
case 4: return cfCaption('transfersFinished');
case 5: return cfCaption('transfersPaused');
case 6: return cfCaption('transfersCanceled');
case 7: return cfCaption('transfersConnecting');
case 8: return cfCaption('transfersFailed');
}
}
// Return true if transfer display needs to be consistently refreshed (depending on status)
public function needRefresh(){
if($this->status==0 || $this->status==2 || $this->status==3 || $this->status==7 || $this->status==9) return true;
return false;
}
// Stop transfer
public function stop(){
// Ask application to stop transfer
if($this->type=='remoteDownload' || $this->type=='fileTransfer') cfServerSendCommand('transfer action="cancel" transferId="'.$this->id.'"');
else $this->status=9;
return true;
}
// Remove finished transfer from list (or even if not finished if $forceRemove)
public function clear($forceRemove=false){
if($forceRemove || ($this->status==4 || $this->status==6 || $this->status==8)) {
// Ask application to remove transfer from list
if($this->type=='remoteDownload') cfServerSendCommand('transfer action="clear" transferId="'.$this->id.'"');
else $this->status=9;
return true;
}
return false;
}
/**
* @desc Update transfer progress
* @param float $newProgress : new progress (0-1)
* @param boolean $commitToFile : set to true to save transfers to file
*/
public function updateProgress($newProgress, $commitToFile=false){
if(!is_numeric($newProgress)) return false;
$this->progress=max(0,min(1,$newProgress));
$this->lastUpdated=time();
if($commitToFile) $this->commitToFile();
return $this->progress;
}
/**
* @desc Update transfer status
* @param integer $newStatus : new status
* status values :
* created = 0
* waitConfirm = 1
* waitConnection = 2
* running = 3
* finished = 4
* paused = 5
* canceled = 6
* connecting = 7
* failed = 8
* removed = 9
* @param boolean $commitToFile : set to true to save transfers to file
*/
public function updateStatus($newStatus, $commitToFile=false){
if(!is_numeric($newStatus)) return false;
$this->status=$newStatus;
$this->lastUpdated=time();
if($commitToFile) $this->commitToFile();
}
/**
* @desc display a progress bar with title and text % progress
*
* @param mixed $progress : progress value (0-1) or 'U' if unknown (for uploads)
* @param integer $width : width of progressbar in px
* @param integer $height : height of progressbar in px
*/
public function tProgressBar($width){
// If transfer is upload, update progress from file... when uploadprogress extension will work.
if(false && $this->type=='upload'){
$ul_info = uploadprogress_get_info($this->id);
if(!$ul_info || !isset($ul_info['bytes_total']) || $ul_info['bytes_total']==0) $progress='U';
else $progress=$ul_info['bytes_total']/$ul_info['bytes_total'];
}
$progress=$this->progress;
$title=$this->captionStatus();
if(!is_numeric($progress)) {
$progress='U';
//$output= '<span title="'.$title.'">';
}
else{
if($progress<0) $progress=0;
if($progress>1) $progress=1;
//$output='<span title="'.$title.'">';
}
if($progress!=0 && $progress!=1) $title=(round(100*$progress)).'%';
if($this->status==6 || $this->status==8 || $this->status==9) return outProgressBar(-1,$width,($title),false,false);
else return outProgressBar($progress,$width,$title,false,false);
}
}
/**
* @desc cross-session transfer speed limitation
* Used to set a user (group) level download speed limit
*
*/
class transferLimitation{
private $userId; // Transfer user id
private $maxTransferRate; // Maximum transfer rate, in KB/sec
private $totalTransfered;
/**
* @desc Constructor
*
* @param integer $speedLimit : speed limit, bytes per second
*/
function __construct($speedLimit=-1){
$totalTransfered=0;
// User Id
if(isset($_SESSION['user']['id'])) $this->userId=$_SESSION['user']['id'];
else $this->userId=$_SERVER['REMOTE_ADDR'];
// Max transfer rate
if($speedLimit!=-1 && is_numeric($speedLimit)) $this->maxTransferRate=$speedLimit;
else{
$this->maxTransferRate=0;
if(isset($_SESSION['user']['downloadSpeedLimit']) && is_numeric($_SESSION['user']['downloadSpeedLimit']) && $_SESSION['user']['downloadSpeedLimit']!=0) $this->maxTransferRate=$_SESSION['user']['downloadSpeedLimit'];
}
if($this->maxTransferRate) customTLCreate($this->userId, time(), $this->maxTransferRate);
}
// Destructor
function __destruct(){customTLDestroy($this->userId, time());}
/**
* @desc Update speed limit
*
* @param unknown_type $speedLimit
*/
function setSpeedLimit($speedLimit){
if($this->maxTransferRate==$speedLimit) return;
$this->maxTransferRate=$speedLimit;
customTLUpdate($this->userId, time(), $speedLimit);
}
/**
* @desc Indicate new data has been transfered, and wait until average transfer rate is below max transfer rate
* @param integer $nbBytes : number of bytes sent
* @param boolean $isTotal : true if $nbBytes is total sent, false if $nbBytes is new data sent
* @param boolean $blocking : true if this function should include tempo
*/
public function addData($nbBytes, $isTotal=false, $blocking=true) {
if(!$this->maxTransferRate) return;
if($isTotal){
customTLAddData($this->userId, time(),$nbBytes - $this->totalTransfered);
$this->totalTransfered=$nbBytes;
}
else{
customTLAddData($this->userId, time(),$nbBytes);
$this->totalTransfered+=$nbBytes;
}
// Wait until average transfer rate is below max transfer rate
if($blocking) {while (!customTLIsReady($this->userId, time())) usleep(300000);}
}
/**
* @desc Return true if data can be sent, false if over limit
*
* @return boolean
*/
public function isReady(){return customTLIsReady($this->userId, time());}
public function debugView(){
customTest($this->userId);
}
}
/**
* @desc write uploads and downloads into transfer file (data dir /uploads.txt)
overwrite all transfers with $transfersArray
*
* @param array $transfersArray: array of transfers to write
* @param mixed $commitToFile:
* set to true to save to disk & memory, false to save to memory only, 'time' to commit only if last commit is old enough
* @return string : time.microtime of save
*/
function tWritePHPTransfersFile($transfersArray, $commitToFile=true){
// Clear finished transfers and detect aborted downloads
foreach ($transfersArray as $key=>$value){
if($value->status==9) unset($transfersArray[$key]);
// Detect aborted downloads
if($value->type=='download' && $value->status==3 && (time()-$value->lastUpdated)>(2*$value->updateInterval)) {
$transfersArray[$key]->status=6;
}
}
// Transfer saved time
$time=time().'.'.microtime();
// Save to memory
cfMSetVar('weezoTransfers',$transfersArray);
$lastSave=(int)cfMGetVar('weezoTransfersLastUpdate');
cfMSetVar('weezoTransfersLastUpdate',$time);
// Check if upload.txt file must be updated
if($commitToFile===false || ($commitToFile=='time' && time()-$lastSave<cfHGetVar('transfersFileUpdateInterval',3))) return $time;
if(!$handle=fopen(cfAppDataDir().'/uploads.txt','w')) return false;
// Write uploads, downloads and bittorrent downloads (if status is not 'cleared' (9))
foreach ($transfersArray as $value){
if(($value->type=='upload' || $value->type=='download' || $value->type=='bittorrentDownload' || $value->type=='multipleDownload') && $value->status!=9){
fwrite($handle, '['.$value->id."]\n");
fwrite($handle, 'type='.$value->type."\n");
fwrite($handle, 'sessionId='.$value->sessionId."\n");
fwrite($handle, 'sessionIP='.$value->sessionIP."\n");
// Detect aborted downloads and multiple downloads
if(($value->type=='download' ||$value->type=='multipleDownload') && $value->status==3 && (time()-$value->lastUpdated)>(2*$value->updateInterval)) $value->status=6;
fwrite($handle, 'status='.$value->status."\n");
fwrite($handle, 'progress='.$value->progress."\n");
fwrite($handle, 'size='.$value->size."\n");
fwrite($handle, 'startTime='.$value->startTime."\n");
fwrite($handle, 'lastUpdated='.$value->lastUpdated."\n");
if($value->sourceFile) fwrite($handle, 'sourceFile='.$value->sourceFile."\n");
fwrite($handle, 'destinationFile='.$value->destinationFile."\n");
if($value->type=='upload') fwrite($handle, 'destinationDir='.$value->destinationDir."\n");
// Bittorrent download specific
if($value->infoHash) fwrite($handle, 'infoHash='.$value->infoHash."\n");
if($value->trackerIdSet) fwrite($handle, 'trackerIdSet=true'."\n");
if($value->userId) fwrite($handle, 'userId='.$value->userId."\n");
if($value->filesOffsets) fwrite($handle, 'filesOffsets='.$value->filesOffsets."\n");
if($value->pieces) fwrite($handle, 'pieces='.$value->pieces."\n");
if($value->pieceLength) fwrite($handle, 'pieceLength='.$value->pieceLength."\n");
if($value->linkedTransferToken) fwrite($handle, 'linkedTransferToken='.$value->linkedTransferToken."\n");
if($value->sentDataLength) fwrite($handle, 'sentDataLength='.$value->sentDataLength."\n");
fwrite($handle,"\n");
}
}
fclose($handle);
return $time;
}
/**
* @desc parse transfers file and return an array of transfers
* @param boolean $forceReadFromFile : set to true to ignore memory cache
* @return array : read transfers
*/
function tReadTransfersFiles($forceReadFromFile=false){
$transfersArray=array();
// If already loaded, read from memory
if(cfMIssetVar('weezoTransfers') && !$forceReadFromFile){
$parsedFile2=cfMGetVar('weezoTransfers');
foreach ($parsedFile2 as $id=>$value) if($value->type=='remoteDownload') unset($parsedFile2[$id]);
}
// Else read uploads and downloads file
else {if(!$parsedFile2=cfParse_ini_file(cfAppDataDir().'/uploads.txt',true)) $parsedFile2=array();}
// Read remote downloads file
if(!$parsedFile=cfParse_ini_file(cfAppDataDir().'/transfers.txt',true)) $parsedFile=array();
// Initialize last update if not set
if(!cfMIssetVar('weezoTransfersLastUpdate')) cfMSetVar('weezoTransfersLastUpdate',time().'.'.microtime());
// Browse merged files
foreach (array_merge($parsedFile, $parsedFile2) as $id=>$value){
if(!is_array($value)) $transfersArray[$id]=$value;
elseif(isset($value['type'])){
$transfersArray[$id]=new transfer($value['type']);
$transfersArray[$id]->id=$id;
$transfersArray[$id]->type=$value['type'];
if(isset($value['sessionId'])) $transfersArray[$id]->sessionId=$value['sessionId'];
if(isset($value['sessionIP'])) $transfersArray[$id]->sessionIP=$value['sessionIP'];
if(isset($value['status'])) $transfersArray[$id]->status=$value['status'];
if(isset($value['progress'])) $transfersArray[$id]->progress=str_replace(',','.',$value['progress']);
if(isset($value['lastUpdated'])) $transfersArray[$id]->lastUpdated=$value['lastUpdated'];
if(isset($value['startTime'])) $transfersArray[$id]->startTime=$value['startTime'];
if(isset($value['infoHash'])) $transfersArray[$id]->infoHash=$value['infoHash'];
if(isset($value['filesOffsets'])) $transfersArray[$id]->filesOffsets=$value['filesOffsets'];
if(isset($value['pieces'])) $transfersArray[$id]->pieces=$value['pieces'];
if(isset($value['pieceLength'])) $transfersArray[$id]->pieceLength=$value['pieceLength'];
if(isset($value['sentDataLength'])) $transfersArray[$id]->sentDataLength=$value['sentDataLength'];
if(isset($value['linkedTransferToken'])) $transfersArray[$id]->linkedTransferToken=$value['linkedTransferToken'];
if(isset($value['size'])) $transfersArray[$id]->size=$value['size'];
if(isset($value['trackerIdSet'])) $transfersArray[$id]->trackerIdSet=$value['trackerIdSet'];
if(isset($value['userId'])) $transfersArray[$id]->userId=$value['userId'];
// Detect aborted downloads
if($transfersArray[$id]->type=='download' && $transfersArray[$id]->status==3 && (time()-$transfersArray[$id]->lastUpdated)>(2*$transfersArray[$id]->updateInterval)) {
$transfersArray[$id]->status=6;
$transfersArray[$id]->progress=0;
}
if(isset($value['destinationDir'])) $transfersArray[$id]->destinationDir=str_replace('\\','/',$value['destinationDir']);
if(isset($value['destinationFile'])) {$transfersArray[$id]->destinationFile=str_replace('\\','/',$value['destinationFile']);$transfersArray[$id]->sourceFile=basename($value['destinationFile']); }
if(isset($value['sourceFile'])) $transfersArray[$id]->sourceFile=$value['sourceFile'];
if(isset($value['url'])) $transfersArray[$id]->URL=$value['url'];
if(isset($value['host'])) $transfersArray[$id]->host=$value['host'];
if(isset($value['path'])) $transfersArray[$id]->path=$value['path'];
// Validate loaded data
if(!isset($value['sessionId']) || !isset($value['sessionIP']) || !isset($value['status']) || !isset($value['progress'])) unset($transfersArray[$id]);
switch ($value['type']){
case 'upload':
if(!isset($value['destinationFile']) || !isset($value['sourceFile']) || !isset($value['destinationDir'])) unset($transfersArray[$id]);
break;
case 'download':
if(!isset($value['destinationFile']) || !isset($value['sourceFile']) || !isset($value['lastUpdated'])) unset($transfersArray[$id]);
break;
case 'multipleDownload':
if(!isset($value['destinationFile']) || !isset($value['sourceFile']) || !isset($value['lastUpdated'])) unset($transfersArray[$id]);
break;
case 'remoteDownload':
if(!isset($value['destinationFile']) || !isset($value['destinationDir']) || !isset($value['host']) || !isset($value['url']) || !isset($value['path'])) unset($transfersArray[$id]);
break;
case 'bittorrentDownload':
if(!isset($value['sourceFile']) || !isset($value['infoHash']) || !isset($value['filesOffsets']) || !isset($value['pieces']) || !isset($value['pieceLength'])) unset($transfersArray[$id]);
break;
default:
unset($transfersArray[$id]);
}
}
}
unset($parsedFile); unset($parsedFile2);
// Save loaded transfers into memory
cfMSetVar('weezoTransfers',$transfersArray);
return $transfersArray;
}
/**
* @desc Inform that a new file upload is about to start
generate an ID for this upload
add it to transfers list
*
* @param string $directory : directory where file should be uploaded
* @param string $fileName : uploaded file name
* @return transfer : created transfer
*/
function tAddUpload($directory, $fileName){
//if(!cfFileRights($directory=cfCleanPathName($directory),'write')) return false;
$tr=new transfer('upload');
$tr->sourceFile=$fileName;
$tr->destinationDir=$directory;
$tr->destinationFile=$fileName;
$tr->status=3;
$tr->progress='U';
$tr->commitToFile();
return $tr;
}
/**
* @desc Inform that a new file download is starting
generate an ID for this download
add it to transfers list
*
* @param string $fileName : downloaded file name
* @return transfer : created transfer
*/
function tAddDownload($fileName){
$tr=new transfer('download');
$tr->sourceFile=$fileName;
$tr->destinationFile=basename($fileName);
$tr->status=3;
$tr->progress=0;
$tr->commitToFile();
return $tr;
}
/**
* @desc Inform that a new file upload is about to start
generate an ID for this upload
add it to transfers list
*
* @param string $directory : directory where file should be uploaded
* @param string $fileName : uploaded file name
* @return transfer : created transfer
*/
function tAddRemoteDownload($dir, $url){
//if(!cfFileRights($directory=cfCleanPathName($directory),'write')) return false;
// Check passed URL
$parsed=@parse_url($url);
if(!(isset($parsed['host'])) || !isset($parsed['path'])) return false;
// Create transfer object
$tr=new transfer('remoteDownload');
$tr->sourceFile=basename($parsed['path']);
$tr->destinationDir=cfCleanPathName($dir);
$tr->destinationFile=rawurldecode(basename($parsed['path']));
$tr->URL=$url;
$tr->host=$parsed['host'];
$tr->path=$parsed['path'];
$tr->status=2;
$tr->lastUpdated=time();
$tr->progress=0;
//$tr->commitToFile();
// Generate command string
$command='transfer transferId="'.$tr->id.'" type="remoteDownload" action="start" destinationDir="'.$dir.'" url="'.$url.'" host="'.$parsed['host'].'" path="'.$parsed['path'].'" startTime="'.$tr->startTime.'" lastUpdated="'.$tr->lastUpdated.'" destinationFile="'.$tr->destinationFile.'"';
if(isset($parsed['user'])) $command=$command.' user="'.$parsed['user'].'"';
if(isset($parsed['pass'])) $command=$command.' pass="'.$parsed['pass'].'"';
if(isset($parsed['query'])) $command=$command.' query="'.$parsed['query'].'"';
// Send command to application to generate and start transfer
if(!cfServerSendCommand($command)) return false;
return $tr;
}
/**
* @desc Create new bittorrent download
*
* @param array $files : array of files and folders to include in torrent
* @param string $metainfo: binary content of .torrent file
* @param array $linkedTransferToken: id of linked directLink or publishDownload token
* @param array $options: jsSyncMonitorFunction=>javascript function name: async update progress passing progress percentage (0-100)
* @return transfer: created transfer, false if failure
*/
function tAddBittorrentDownload($files, &$metainfo, $linkedTransferToken=false,$options=array()){
// Create File_Bittorrent_MakeTorrent object
$version=2; // fileBittorrent library version
if ($version==1){
require_once(INCLUDE_DIR.'fileBittorrent/MakeTorrent.php');
$MakeTorrent = new File_Bittorrent_MakeTorrent($files);
}
elseif($version==2){
require_once(INCLUDE_DIR.'File/Bittorrent2/MakeTorrent.php');
$MakeTorrent = new File_Bittorrent2_MakeTorrent($files);
}
// Set the announce URL
// Registered users : use weezo.net as tracker
if($regInfo=cfIsRegistered())
$trackerURL='http://weezo.net:80/tracker.php?userName='.$regInfo['regName'].'&lng='.cfGGetVar('language');
// Else, use server as tracker
else
$trackerURL=cfGGetVar('hostName').'/bittorrentTracker.php?lng='.cfGGetVar('language');
$trackerURL.='&bittorrentPort='.cfGGetVar('bittorrentPort');
$MakeTorrent->setAnnounce($trackerURL);
// Set the comment
$MakeTorrent->setComment('Generated by Weezo on '.date(cfCaption('_FULL_DATE_FORMAT')));
// Set the piece length (in KB)
$MakeTorrent->setPieceLength(1024);
// Set the piece length (in KB)
//$MakeTorrent->setIsPrivate();
// Set Javascript monitoring function
if(isset($options['jsSyncMonitorFunction'])) $MakeTorrent->setJsSyncMonitorFunction($options['jsSyncMonitorFunction']);
// Build the torrent
$metainfo = $MakeTorrent->buildTorrent($files);
if(!$metainfo) return false;
// Create transfer
$tr=new transfer('bittorrentDownload');
$tr->destinationFile=$MakeTorrent->torrentName;
$tr->infoHash=$MakeTorrent->infoHash;
// Generate source files list
$str=''; foreach ($files as $file) $str.=$file.'|';
$tr->sourceFile=$str;
// Generate files/offset data
$str=''; foreach ($MakeTorrent->files as $file) $str.=$file['name'].'?'.$file['offset'].'|';
$tr->filesOffsets=$str;
$tr->pieces=(strlen($MakeTorrent->pieces)/20);
$tr->pieceLength=$MakeTorrent->piece_length;
$tr->size=$MakeTorrent->dataLength;
$tr->status=2;
$tr->progress=0;
$tr->sentDataLength=0;
$tr->userId=cfUGetVar('id');
$tr->linkedTransferToken=$linkedTransferToken;
$tr->commitToFile();
return $tr;
}
/**
* @desc Inform that a new multiple (zip) download is starting
generate an ID for this download
add it to transfers list
*
* @param string $outputFilename : zip file name
* @return transfer : created transfer
*/
function tAddMultipleDownload($outputFilename){
$tr=new transfer('multipleDownload');
// Generate source files list
$str='';
$sfl=cfRGetVar('mDownloadList');
if(is_array($sfl) && @count($sfl)) foreach (array_values($sfl) as $file) $str.=$file.'|';
$tr->sourceFile=$str;
// Get total unziped size
if(cfHGetVar('mDownloadPrecomputeSize')) list($nbFiles,$tr->size)=cfRGetVar('mDownloadTotals'); else $tr->size=0;
$tr->destinationFile=($outputFilename);
$tr->status=3;
$tr->progress=0;
$tr->commitToFile();
return $tr;
}
/*
***************************************************************************************************************************
* Transfer pages
***************************************************************************************************************************
*/
/**
* @desc display transfers page
*
* @param boolean $standalone : true if page should include html head and body
* @param string $bodyClass optional : class of body
*/
function tDisplayTransfers($standalone, $bodyClass=false){
if(!isset($_ENV['configurationEnvironment'])) $_ENV['configurationEnvironment']='browser';
require_once(INCLUDE_DIR.'outputFunctions.php');
// read transfers from files
$transfersArray=tReadTransfersFiles();
/*
***************************************************************************************************************************
* Process POST Commands
***************************************************************************************************************************
*/
// Command sent through StandardComForm
if(isset($_POST['data2']) && isset($_POST['data3'])){
if($standalone) $asyncResponse=true; else $asyncResponse=false;
$tId=cfUTF8Decode($_POST['data2']); $action=cfUTF8Decode($_POST['data3']);
if($tId=='all' && ($action=='clear' || $action=='kill')) {
foreach ($transfersArray as $key=>$value){
if(cfUGetVar('administrator') || $value->sessionId==wSession_id() || cfIsInApp()){
$value->clear($action=='kill');
}
}
//sleep(1);
tWritePHPTransfersFile($transfersArray);
if($asyncResponse){
cfAsyncHeader();
echo cfAsyncXMLJSaction('if(dgi("transfersIFrame")) frames["transfersIFrame"].refresh();');
echo cfAsyncFooter();
exit();
}
}
// Check if transfer exists and user is allowed to interact
elseif(isset($transfersArray[$_POST['data2']]) && (cfUGetVar('administrator') || $transfersArray[$_POST['data2']]->sessionId==wSession_id() || cfIsInApp())){
$transfer=$transfersArray[$_POST['data2']];
// STOP (unfinished) transfer
if($_POST['data3']=='stop') {$transfer->stop(); $transfer->commitToFile();}
if($_POST['data3']=='clear') {$transfer->clear(); $transfer->commitToFile();}
// If transfer is not an upload, let 1 sec to server to remove transfer from file
if($transfer->type=='remoteDownload') sleep(1);
// Re-read transfers file
unset($transfersArray); $transfersArray=tReadTransfersFiles();
}
}
// Async refresh requested
elseif (isset($_POST['refresh'])) $asyncResponse=true;
// Else, display full page
else $asyncResponse=false;
/*
***************************************************************************************************************************
* IFRAME page
***************************************************************************************************************************
*/
if($standalone){
/*
* HEAD
*/
// Normal (non-async) page head
if(!$asyncResponse){
$_ENV['winNoBar']=true;
cfInsertHEAD(false);
// Javascript stuff...
?>
<script language="javascript" type="text/javascript">
var interval;
function refresh(reupdate) {
window.clearInterval(interval); interval=false;
if(!window.sendData) {};
sendData("refresh=true","<?php echo $_SERVER['PHP_SELF'];?>",false);
if(reupdate) interval=window.setInterval('refresh(false)',2000);
}
function updateInterval(newInterval){
if(interval) window.clearInterval(interval);
interval = window.setInterval("refresh()",newInterval);
}
function stop(id){fillAndSubmit(id,'stop');}
function tClear(id){fillAndSubmit(id,'clear');}
function jsConv(str){return str.replace(/<br>/gi,String.fromCharCode(10));}
</script>
</head>
<?php
// Body
if($bodyClass) echo '<body class="'.$bodyClass.'" style="margin:0px;border:0px;padding:0px">'; else echo '<body>';
// Inser standard com form
outInsertStandardComForm($_SERVER['PHP_SELF'],false,false,false,false,false,true);
echo '<div id="content" style="height:95%"'.outEHoverFrameAttr().'>';
}
// Async response header
else cfAsyncHeader();
/*
* BODY
*/
// Display transfers
$displayedTransfers=0; $needRefresh=false;$output='';
if(is_array($transfersArray)){
$output.= outTableTransparent(false,'table-layout:fixed');
$output.= '<colgroup><col width="40"><col width="20"><col width="180"><col width="*"><col width="20"></colgroup>';
// Display transfer if it belongs to user or if user is administrator
foreach ($transfersArray as $id=>$transfer) if($transfer->status!=9){
if(cfUGetVar('administrator') || $transfer->sessionId==wSession_id()){
$output.='<tr id="tr'.$displayedTransfers.'" class="eTC" eH=1 style="padding-left:0.5em;cursor:default">'."\n";
// Transfer Icon
if($transfer->type=='upload') $output.='<td>'.outImage(outIcon('upload'),false,'title="'.cfCaption('genFileUpload').'"').'</td>';
elseif($transfer->type=='remoteDownload') $output.= '<td>'.outImage(outIcon('ddl'),false,'title="'.cfCaption('genDirectDownload').'"').'</td>';
elseif($transfer->type=='download') $output.= '<td>'.outImage(outIcon('tdl'),false,'title="'.cfCaption('transfersDownload').'"').'</td>';
elseif($transfer->type=='multipleDownload') $output.= '<td>'.outImage(outIcon('tmdl'),false,'title="'.cfCaption('explorerMultipleDownload').'"').'</td>';
elseif($transfer->type=='bittorrentDownload') $output.= '<td>'.outImage(outIcon('tbtdl'),false,'title="'.cfCaption('bittorrent').'"').'</td>';
// Detail button
$output.= '<td>'.outButtonSmall('', 'javascript:alert(jsConv(\''.addslashes($transfer->detail(false)).'\'))', outIcon('info'), cfCaption('genDetails')).'</td>';
// Progress bar
$output.= '<td>'.$transfer->tProgressBar('180px').'</td>';
// File name
$output.= '<td style="width:100%;padding-left:0.5em; position:relative;;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">'.cfUTF8Encode(basename($transfer->destinationFile)).'</td>';
// Clear finished transfers
if($transfer->status==4 || $transfer->status==6 || $transfer->status==8) $output.= '<td>'.outButtonSmall('','javascript:tClear(\''.$transfer->id.'\')',outIcon('eraser'),cfCaption('transferRemove')).'</td>';
// Stop transfer
elseif($transfer->progress!=1 || $transfer->type=='bittorrentDownload') $output.= '<td>'.outButtonSmall('','javascript:stop(\''.$transfer->id.'\')',outIcon('cancel'),cfCaption('genCancel')).'</td>';
else $output.= '<td></td>';
$output.= "</tr>\n";
if($transfer->needRefresh()) $needRefresh=true;
$displayedTransfers++;
}
}
$output.="</table>\n";
}
// If no transfer, display "no transfer" message
if(!$displayedTransfers){
$output=''; // reset output
$output.= outTableTransparent($bodyClass,false, 'height="95%" width="100%", id="noTransferTable"');
$output.= '<tr><td height="100%" valign="middle" align="center">'.cfCaption('activityNoTransfer')."</td></tr></table>\n";
}
// Flush page to output (XML response or HTML page)
cfAsyncOutputFlush($output,$asyncResponse,false,'<innerHTML nodeId="content">',false);
// if at least one tranfer is active, indicate that page need to be (async) reloaded in a few seconds, else set to transferIdleRefreshRate
if($needRefresh) $interval=max(cfHGetVar('transferRefreshRate',2.5)*1000,1000); else $interval=cfHGetVar('transferIdleRefreshRate',10)*1000;
if($asyncResponse)
echo cfAsyncXMLJSaction('updateInterval('.$interval.')');
else
echo '<script language="javascript" type="text/javascript">updateInterval('.$interval.");</script>\n";
/*
* FOOTER
*/
if($asyncResponse) echo cfAsyncFooter(); else echo '</div></body></html>';
}
/*
***************************************************************************************************************************
* Administration / Application page
***************************************************************************************************************************
*/
else{
// Javascript stuff...
echo '<script language="javascript" type="text/javascript">'."\nvar interval;\n";
echo 'function refresh() {window.clearInterval(interval);sendData("refresh=true","'.$_SERVER['PHP_SELF'].'",false);}';
?>
function stop(id){fillAndSubmit(id,'stop');}
function tClear(id){fillAndSubmit(id,'clear');}
function jsConv(str){return str.replace(/<br>/gi,String.fromCharCode(10));}
<?php
echo "</script>\n";
// Insert standard com form
outInsertStandardComForm($_SERVER['PHP_SELF']);
// Display transfers
$displayedTransfers=0; $needRefresh=false;$output='';
if(is_array($transfersArray)){
$output.=outTableTransparent((cfIsInApp())?'frame1':'',false,'');
$output.= '<colgroup><col width="50"><col width="80"><col width="160"><col width="70"><col width="200"><col width="*"><col width="45"><col width="45"></colgroup>';
// Display transfer if it belongs to user or if user is administrator (note : only administrator can access this script)
foreach ($transfersArray as $id=>$transfer) if($transfer->status!=9){
if(cfUGetVar('administrator') || (cfIsInApp()) || $transfer->sessionId==wSession_id()){
$output.='<tr id="tr'.$displayedTransfers.'" class="eTC" eH=1 style="padding-left:0.5em;cursor:default;margin-bottom:10px" align="left">'."\n";
// Transfer Icon
$output.='<td class="eTCLeft">';
if($transfer->type=='upload') $output.=outImage(outIcon('upload'),false,'title="'.cfCaption('genFileUpload').'"').'</td>';
elseif($transfer->type=='remoteDownload') $output.=outImage(outIcon('ddl'),false,'title="'.cfCaption('genDirectDownload').'"').'</td>';
elseif($transfer->type=='download') $output.=outImage(outIcon('tdl'),false,'title="'.cfCaption('transfersDownload').'"').'</td>';
elseif($transfer->type=='multipleDownload') $output.=outImage(outIcon('tmdl'),false,'title="'.cfCaption('explorerMultipleDownload').'"').'</td>';
elseif($transfer->type=='bittorrentDownload') $output.=outImage(outIcon('tbtdl'),false,'title="'.cfCaption('bittorrent').'"').'</td>';
// Transfer date
$output.='<td>'.date(cfCaption('_FULL_DATE_FORMAT'),$transfer->startTime).' </td>';
// Transfer source
$output.='<td>'.cfCaption('transferCfgSource').' : '.$transfer->sessionIP.'</td>';
// Transfer Status
$output.='<td>'.$transfer->captionStatus().'</td>';
// Progress bar
if(cfIsInApp()) $output.='<td height=40><div style="padding-top:2px">'.$transfer->tProgressBar('280px').'</div>';
else $output.= '<td>'.$transfer->tProgressBar('280px').'</td><td>';
// Source URL, complete destination file name
if($transfer->type=='upload') $output.= '<span style="margin-left:0.5em">'.cfUTF8Encode($transfer->sourceFile).' -> '.cfUTF8Encode(str_replace('\\','/',$transfer->destinationFile)).'</span></td>';
elseif($transfer->type=='remoteDownload') $output.= '<span style="margin-left:0.5em;">'.cfUTF8Encode(basename($transfer->host)).' -> '.cfUTF8Encode(str_replace('\\','/',$transfer->destinationFile)).'</span></td>';
elseif($transfer->type=='download') $output.= '<span style="margin-left:0.5em">'.cfUTF8Encode($transfer->sourceFile).'</span></td>';
if(cfIsInApp()) $output.='<td> </td>';
// Clear finished transfers
if($transfer->status==4 || $transfer->status==6 || $transfer->status==8) $output.= '<td nowrap="nowrap">'.outButton('','javascript:tClear(\''.$transfer->id.'\')',outIcon('eraser'),cfCaption('transferRemove')).'</td>';
// Stop transfer
elseif($transfer->progress!=1) $output.= '<td nowrap="nowrap">'.outButton('','javascript:stop(\''.$transfer->id.'\')',outIcon('cancel'),cfCaption('genCancel')).'</td>';
else $output.= '<td> </td>';
// Detail button
$output.= '<td class="eTCRight" nowrap="nowrap"><span style="display:none" id="hlpLb'.$id.'">'.$transfer->detail(false).'</span>'.outButton('', 'javascript:alert(jsConv(dgi(\'hlpLb'.$id.'\').innerHTML))', outIcon('info'), cfCaption('genDetails')).'</td>';
$output.= "</tr>\n";
if(cfIsInApp()) $output.='<tr height=3><td></td></tr>';
if($transfer->needRefresh()) $needRefresh=true;
$displayedTransfers++;
}
}
$output.="</table><br>\n";
}
// If no transfer, display "no transfer" message
if(!$displayedTransfers){
$output=''; // reset output
$output.= '<span style="padding-top:14em;padding-bottom:14em;text-align:center;display:block">'.cfCaption('activityNoTransfer')."</span>\n";
}
// Flush page to output (XML response or HTML page)
cfAsyncOutputFlush($output,$asyncResponse,false,false,false);
}
return $displayedTransfers;
}
/**
* @desc remove a transfer from transfers list
*
* @param string $transferId: id of transfer to remove
*/
function tRemoveTransfer($transferId){
$transfersArray=tReadTransfersFiles();
if(isset($transfersArray[$transferId])){
$transfersArray[$transferId]->clear(true);
tWritePHPTransfersFile($transfersArray,true);
}
}
?>